package com.chisheng.caa.util;

import cn.hutool.core.bean.copier.CopyOptions;
import lombok.SneakyThrows;

import java.util.Map;

/**
 * Bean 工具类
 */
public final class BeanUtil {

    private BeanUtil() {
        throw new UnsupportedOperationException();
    }

    /**
     * 复制 Bean 对象属性。
     *
     * @param source          源 Bean 对象
     * @param clazz           目标 Bean 类型
     * @param ignoreNullValue 是否忽略空值
     * @return 目标 Bean 对象
     */
    public static <T> T copyProperties(Object source, Class<T> clazz, boolean ignoreNullValue) {
        CopyOptions options = CopyOptions.create();
        options.setIgnoreNullValue(ignoreNullValue);
        return copyProperties(source, clazz, options);
    }

    /**
     * 复制 Bean 对象属性。
     *
     * @param source          源 Bean 对象
     * @param dest            目标 Bean 对象
     * @param ignoreNullValue 是否忽略空值
     * @return 目标 Bean 对象
     */
    public static <T> T copyProperties(Object source, T dest, boolean ignoreNullValue) {
        CopyOptions options = CopyOptions.create();
        options.setIgnoreNullValue(ignoreNullValue);
        cn.hutool.core.bean.BeanUtil.copyProperties(source, dest, options);
        return dest;
    }

    /**
     * 复制 Bean 对象属性。
     *
     * @param source           源 Bean 对象
     * @param clazz            目标 Bean 类型
     * @param ignoreProperties 忽略的属性
     * @return 目标 Bean 对象
     */
    public static <T> T copyProperties(Object source, Class<T> clazz, String... ignoreProperties) {
        CopyOptions options = CopyOptions.create().setIgnoreProperties(ignoreProperties);
        return copyProperties(source, clazz, options);
    }

    /**
     * 复制 Bean 对象属性。
     *
     * @param source           源 Bean 对象
     * @param dest             目标 Bean 对象
     * @param ignoreProperties 忽略的属性
     * @return 目标 Bean 对象
     */
    public static <T> T copyProperties(Object source, T dest, String... ignoreProperties) {
        CopyOptions options = CopyOptions.create().setIgnoreProperties(ignoreProperties);
        cn.hutool.core.bean.BeanUtil.copyProperties(source, dest, options);
        return dest;
    }

    /**
     * 复制 Bean 对象属性，目标类必须提供无参构造。
     *
     * @param source 源 Bean 对象
     * @param clazz  目标 Bean 类型
     * @return 目标 Bean 对象
     */
    @SneakyThrows
    public static <T> T copyProperties(Object source, Class<T> clazz, CopyOptions options) {
        T dest = clazz.getConstructor().newInstance();
        cn.hutool.core.bean.BeanUtil.copyProperties(source, dest, options);
        return dest;
    }

    /**
     * Bean 对象属性转换为 Map
     *
     * @param obj             Bean 对象
     * @param ignoreNullValue 是否忽略值为 null 的属性
     * @return 属性 Map
     */
    public static Map<String, Object> beanToMap(Object obj, boolean ignoreNullValue) {
        return cn.hutool.core.bean.BeanUtil.beanToMap(obj, false, ignoreNullValue);
    }

    /**
     * 返回 Bean 对象非 null 值的属性名数组
     *
     * @param obj Bean 对象
     * @return 属性名数组
     */
    public static String[] nonnullProperties(Object obj) {
        return beanToMap(obj, true).keySet().toArray(new String[0]);
    }


}
